{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "189_HW6_Q4_G.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.8"
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "nd8iaSjXiICq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "%load_ext autoreload\n",
        "%autoreload 2"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "TosggIXPCqDI",
        "colab": {}
      },
      "source": [
        "import os, sys\n",
        "from google.colab import drive\n",
        "drive.mount('/gdrive')\n",
        "sys.path.insert(0, \"/content/gdrive/My Drive/CS 189/hw/hw6-collabtry/\")\n",
        "%cd /gdrive/My\\ Drive/CS\\ 189/hw/hw6-collabtry/"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aSE2LyHNIN2K",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import numpy as np\n",
        "from torchsummary import summary\n",
        "import pandas as pd\n",
        "from sklearn.metrics import confusion_matrix\n",
        "import pickle\n",
        "import torch"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t0WRrf1_iICw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!pip install torchsummary"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EbovbNsOHYUh",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#https://github.com/Luolc/AdaBound\n",
        "!pip install adabound"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ormkojCMiIC7",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "np.random.seed(10)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zzYBme3CiIDA",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = []"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "S5Hf7oFCiIDE",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "%matplotlib inline\n",
        "import time\n",
        "import pylab as pl\n",
        "from IPython import display\n",
        "\n",
        "\n",
        "def plot_kaggleloss(arch,train,val,status=None,extra=None):\n",
        "    title = arch\n",
        "    pl.figure().legends = []\n",
        "    if status:\n",
        "      a,b,c,d = status\n",
        "      title += ', Epoch [{}/{}], Step [{}/{}]'.format(a,b,c,d)\n",
        "    if len(train) > 0:\n",
        "      mt = sum(train)/len(train)\n",
        "      pl.plot(train, 'r', label=\"train\")\n",
        "      title += \", Avg Train Loss: \"+str(round(mt,4))\n",
        "    if len(val) > 0:\n",
        "      mv = sum(val)/len(val)\n",
        "      pl.plot(val, 'b', label=\"validation\")\n",
        "      title+=\", Avg Val Loss: \"+str(round(mv,4))\n",
        "    if extra is not None:\n",
        "      title+=\", Current Val Acc: \"+str(round(extra,4))\n",
        "    pl.title(title)\n",
        "    pl.xlabel(\"steps\")\n",
        "    pl.ylabel(\"loss\")\n",
        "    pl.legend()\n",
        "    display.clear_output(wait=True)\n",
        "    display.display(pl.gcf())\n",
        "    time.sleep(1.0)\n",
        "    \n",
        "def data_track(data=None,save=True):\n",
        "    if save and len(data) > 0:\n",
        "        with open(\"datakaggle.txt\", \"wb\") as file:   #Pickling\n",
        "            pickle.dump(data, file)\n",
        "        torch.cuda.empty_cache()\n",
        "    else:\n",
        "        torch.cuda.empty_cache()\n",
        "        with open(\"datakaggle.txt\", \"rb\") as file:   # Unpickling\n",
        "            return pickle.load(file)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "J2MzPDCxRoFu",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "from torch.utils import data\n",
        "import pandas as pd\n",
        "import random\n",
        "import json\n",
        "import numpy as np\n",
        "from skimage import io, transform\n",
        "from PIL import Image\n",
        "\n",
        "class Mds189(data.Dataset):\n",
        "    'Characterizes a dataset for PyTorch'\n",
        "    def __init__(self, label_file, loader, transform):\n",
        "        'Initialization'\n",
        "        self.label_file = label_file\n",
        "        self.loader = loader\n",
        "        self.transform = transform\n",
        "        self.label_map = ['reach','squat','pushup','inline',\n",
        "                          'hamstrings','lunge','deadbug','stretch']\n",
        "        self.data= pd.read_csv(self.label_file,header=None)\n",
        "\n",
        "    def __len__(self):\n",
        "        'Denotes the total number of samples'\n",
        "        return len(self.data)\n",
        "\n",
        "    def map_label_to_int(self,y):\n",
        "        'The labels need to be integers'\n",
        "        label_map = {'reach_both': 0,        # the key frames are labeled with the side\n",
        "                     'squat_both': 1,\n",
        "                     'inline_left': 2,\n",
        "                     'inline_right': 2,\n",
        "                     'lunge_left': 3,\n",
        "                     'lunge_right': 3,\n",
        "                     'hamstrings_left': 4,\n",
        "                     'hamstrings_right': 4,\n",
        "                     'stretch_left': 5,\n",
        "                     'stretch_right': 5,\n",
        "                     'deadbug_left': 6,\n",
        "                     'deadbug_right': 6,\n",
        "                     'pushup_both': 7,\n",
        "                     'reach': 0,            # the video frames don't have information about which side is moving \n",
        "                     'squat': 1,\n",
        "                     'inline': 2,\n",
        "                     'lunge': 3,\n",
        "                     'hamstrings': 4,\n",
        "                     'stretch': 5,\n",
        "                     'deadbug': 6,\n",
        "                     'pushup': 7,\n",
        "                     'label': -1           # label is the placeholder in `videoframe_data_test.txt` for the kaggle frame labels\n",
        "                    }\n",
        "        return label_map[y]\n",
        "\n",
        "    def __getitem__(self,idx):\n",
        "        'Generates one sample of data'\n",
        "        path,target = self.data.iloc[idx]\n",
        "        sample = self.loader(path)\n",
        "        if self.transform is not None:\n",
        "            sample = self.transform(sample)\n",
        "        movement = self.map_label_to_int(target)\n",
        "\n",
        "        return sample,movement"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I7uxtEXJPuKT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import os, sys\n",
        "\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "from torch.utils import data\n",
        "import numpy as np\n",
        "from skimage import io, transform\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "from torchvision import transforms\n",
        "import torchvision.models as models\n",
        "from PIL import Image\n",
        "import torch.optim as optim\n",
        "\n",
        "# Helper functions for loading images.\n",
        "def pil_loader(path):\n",
        "    # open path as file to avoid ResourceWarning \n",
        "    #(https://github.com/python-pillow/Pillow/issues/835)\n",
        "    with open(path, 'rb') as f:\n",
        "        img = Image.open(f)\n",
        "        return img.convert('RGB')\n",
        "\n",
        "def accimage_loader(path):\n",
        "    import accimage\n",
        "    try:\n",
        "        return accimage.Image(path)\n",
        "    except IOError:\n",
        "        # Potentially a decoding problem, fall back to PIL.Image\n",
        "        return pil_loader(path)\n",
        "\n",
        "def default_loader(path):\n",
        "    from torchvision import get_image_backend\n",
        "    if get_image_backend() == 'accimage':\n",
        "        return accimage_loader(path)\n",
        "    else:\n",
        "        return pil_loader(path)\n",
        "\n",
        "# CUDA for PyTorch\n",
        "use_cuda = torch.cuda.is_available()\n",
        "device = torch.device(\"cuda:0\" if use_cuda else \"cpu\")\n",
        "#cudnn.benchmark = True\n",
        "\n",
        "def load_preprocess_data(is_train, is_key_frame, params):\n",
        "    \n",
        "    label_file_train, label_file_val, label_file_test = None, None, None\n",
        "    test_dataset, test_loader = None, None\n",
        "    \n",
        "    if is_key_frame:\n",
        "        label_file_train =  'dataloader_files/keyframe_data_train.txt'\n",
        "        label_file_val  =  'dataloader_files/keyframe_data_val.txt'\n",
        "        # NOTE: the kaggle competition test data is only for the video frames, not the key frames\n",
        "        # this is why we don't have an equivalent label_file_test with keyframes\n",
        "    else:\n",
        "        label_file_train = 'dataloader_files/videoframe_data_train.txt'\n",
        "        label_file_val = 'dataloader_files/videoframe_data_val.txt'\n",
        "        label_file_test = 'dataloader_files/videoframe_data_test.txt'\n",
        "        \n",
        "    mean, std = [0,0,0], [0,0,0]\n",
        "    if is_key_frame:\n",
        "      mean = [134.010302198,118.599587912,102.038804945]\n",
        "      std = [23.5033438916,23.8827343458,24.5498666589]\n",
        "    else: \n",
        "      mean = [133.714058398,118.396875912,102.262895484]\n",
        "      std = [23.2021839891,23.7064439547,24.3690056102]\n",
        "    train_dataset = Mds189(label_file_train,loader=default_loader,\\\n",
        "                            transform=transforms.Compose([\n",
        "                              transforms.ToTensor(),\n",
        "                              transforms.Normalize(mean, std)\n",
        "                            ]))\n",
        "    train_loader = data.DataLoader(train_dataset, **params)\n",
        "\n",
        "    val_dataset = Mds189(label_file_val,loader=default_loader,\\\n",
        "                          transform=transforms.Compose([\n",
        "                             transforms.ToTensor(),\n",
        "                             transforms.Normalize(mean, std)\n",
        "                          ]))\n",
        "    val_loader = data.DataLoader(val_dataset, **params)\n",
        "    \n",
        "    if not is_key_frame:\n",
        "        test_dataset = Mds189(label_file_test,loader=default_loader,\\\n",
        "                              transform=transforms.Compose([\n",
        "                                transforms.ToTensor(),\n",
        "                                transforms.Normalize(mean, std)\n",
        "                              ]))\n",
        "        test_loader = data.DataLoader(test_dataset, **params)\n",
        "    \n",
        "    return train_loader, val_loader, test_loader\n",
        "\n",
        "def modelling(model,is_train,is_key_frame,arch,params,hyperparams):\n",
        "    train_loader, val_loader, test_loader = \\\n",
        "    load_preprocess_data(is_train,is_key_frame,params)\n",
        "    train_losses, val_losses = train_val_kagglemodel(model, \n",
        "                                                     train_loader,\n",
        "                                                     val_loader, \n",
        "                                                     hyperparams,params)\n",
        "    return (train_losses, val_losses, arch, params)\n",
        "\n",
        "def get_current_valacc(model,params):\n",
        "  model.load_state_dict(torch.load(os.getcwd()+\"/\"+model.arch))\n",
        "  model.eval()\n",
        "  _,val_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                        is_key_frame=False,\n",
        "                                        params=params)\n",
        "  rand_acc,_,_ = get_accuracy(model, val_loader)\n",
        "  return rand_acc\n",
        "  \n",
        "def train_val_kagglemodel(model, train_loader, val_loader, hyperparams,params=None):\n",
        "    num_epochs,criterion,optimizer = hyperparams[\"num_epochs\"],\\\n",
        "    hyperparams[\"criterion\"],\\\n",
        "    hyperparams[\"optimizer\"]\n",
        "    \n",
        "    print('Beginning training...')\n",
        "    total_step = len(train_loader)\n",
        "    train_losses, val_losses = [], []\n",
        "    train_accs, val_accs = [], []\n",
        "#     scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=2, verbose=True)    \n",
        "    for epoch in range(num_epochs):\n",
        "        for i, (local_batch,local_labels) in enumerate(train_loader):\n",
        "            local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "            outputs = model.forward(local_ims)\n",
        "            loss = criterion(outputs, local_labels)\n",
        "            optimizer.zero_grad()\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            train_losses.append(loss.item())\n",
        "            if (i+1) % 10 == 0:\n",
        "                torch.save(model.state_dict(), os.getcwd()+\"/\"+model.arch)\n",
        "                plot_kaggleloss(model.arch,train_losses,val_losses,\\\n",
        "                                (epoch+1, num_epochs, i+1, total_step))\n",
        "        for i, (local_batch,local_labels) in enumerate(val_loader):\n",
        "            local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "            outputs = model.forward(local_ims)\n",
        "            loss = criterion(outputs, local_labels)\n",
        "            val_losses.append(loss.item())\n",
        "            if (i+1) % 10 == 0:\n",
        "              plot_kaggleloss(model.arch,train_losses,val_losses)\n",
        "        print('finished epoch {}, Training Loss: {:.4f}, Validation Loss: {:.4f}'\n",
        "              .format(epoch+1, train_losses[epoch], val_losses[epoch]))\n",
        "#         scheduler.step(epoch)\n",
        "        plot_kaggleloss(model.arch,train_losses,val_losses)\n",
        "    torch.save(model.state_dict(), os.getcwd()+\"/\"+model.arch)\n",
        "    return (train_losses, val_losses)\n",
        "\n",
        "def get_accuracy(model, loader):\n",
        "    print('Starting accuracy calculation!!!')\n",
        "    with torch.no_grad():\n",
        "      correct = 0\n",
        "      total = 0\n",
        "      predicted_list = []\n",
        "      groundtruth_list = []\n",
        "      for (local_batch,local_labels) in loader:\n",
        "          # Transfer to GPU\n",
        "          local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "\n",
        "          outputs = model.forward(local_ims)\n",
        "          _, predicted = torch.max(outputs.data, 1)\n",
        "          total += local_labels.size(0)\n",
        "          predicted_list.extend(predicted)\n",
        "          groundtruth_list.extend(local_labels)\n",
        "          correct += (predicted == local_labels).sum().item()\n",
        "    \n",
        "    predicted_list = [p.cpu().numpy().tolist() for p in predicted_list]\n",
        "    groundtruth_list = [p.cpu().numpy().tolist() for p in groundtruth_list]\n",
        "    acc = correct / total\n",
        "    print(\"accuracy\",acc)\n",
        "    return acc,predicted_list,groundtruth_list\n",
        "\n",
        "def move_val_acc(pl,gt):\n",
        "    #use pl and gt to produce your confusion matrices\n",
        "\n",
        "    # view the per-movement accuracy\n",
        "    label_map = ['reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup']\n",
        "    pairs = []\n",
        "    print(type(pl),type(gt))\n",
        "    print(\"pl\",pl)\n",
        "    print(\"gt\",gt)\n",
        "    for id in range(len(label_map)):\n",
        "        num = sum([p and g for (p,g) in zip(np.array(pl)==np.array(gt),np.array(gt)==id)])\n",
        "        denom = sum(np.array(gt)==id)+0.\n",
        "        acc = num/denom\n",
        "        move = label_map[id]\n",
        "        pairs.append((acc,move))\n",
        "    return pairs\n",
        "\n",
        "og_map = {'reach_both': 0,        \n",
        "           'squat_both': 1,\n",
        "           'inline_left': 2,\n",
        "           'inline_right': 2,\n",
        "           'lunge_left': 3,\n",
        "           'lunge_right': 3,\n",
        "           'hamstrings_left': 4,\n",
        "           'hamstrings_right': 4,\n",
        "           'stretch_left': 5,\n",
        "           'stretch_right': 5,\n",
        "           'deadbug_left': 6,\n",
        "           'deadbug_right': 6,\n",
        "           'pushup_both': 7,\n",
        "           'reach': 0,             \n",
        "           'squat': 1,\n",
        "           'inline': 2,\n",
        "           'lunge': 3,\n",
        "           'hamstrings': 4,\n",
        "           'stretch': 5,\n",
        "           'deadbug': 6,\n",
        "           'pushup': 7,\n",
        "          }\n",
        "inv_map = dict((v,k) for k,v in og_map.items())\n",
        "\n",
        "def test_predict(model,loader):\n",
        "  print('Starting test predictions!!!')\n",
        "  with torch.no_grad():\n",
        "    predicted_list = []\n",
        "    for (local_batch,local_labels) in loader:\n",
        "        # Transfer to GPU\n",
        "        local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "        outputs = model.forward(local_ims)\n",
        "        _, predicted = torch.max(outputs.data, 1)\n",
        "        predicted_list.extend(predicted)\n",
        "  names = [format(i, '04')+\".jpg\" for i in range(len(predicted_list))]\n",
        "  predicted_list = [inv_map[p.cpu().numpy().tolist()] for p in predicted_list]\n",
        "  return names, predicted_list"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IwbEKCvUWSfe",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# TRY 1\n",
        "# class KaggleNN(nn.Module):\n",
        "#     def __init__(self, arch):\n",
        "#       super(KaggleNN, self).__init__()\n",
        "#       self.arch = arch\n",
        "#       self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "#       self.mp1 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn1 = nn.BatchNorm2d(8)\n",
        "#       self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "#       self.mp2 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn2 = nn.BatchNorm2d(16)\n",
        "#       self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "#       self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "#       self.conv5 = nn.Conv2d(64,128,3,1,1)\n",
        "#       self.mp4 = nn.MaxPool2d(5, 2)        \n",
        "#       self.fc1 = nn.Linear(5632, 2048)\n",
        "#       self.fc2 = nn.Linear(2048, 2048)\n",
        "#       self.fc3 = nn.Linear(2048,8)\n",
        "#     def forward(self, x):\n",
        "#       x = self.bn1(F.leaky_relu(self.mp1(self.conv1(x))))\n",
        "#       x = self.bn2(F.leaky_relu(self.mp2(self.conv2(x))))\n",
        "#       x = self.conv5(self.conv4(self.conv3(x)))\n",
        "#       x = self.mp4(x)\n",
        "#       x = x.view(int(x.size(0)), -1)\n",
        "#       x = self.fc3(F.dropout(self.fc2(F.dropout(self.fc1(x)))))\n",
        "#       return x\n",
        "\n",
        "# TRY 2\n",
        "# class KaggleNN(nn.Module):\n",
        "#     def __init__(self, arch):\n",
        "#       super(KaggleNN, self).__init__()\n",
        "#       self.arch = arch\n",
        "#       self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "#       self.mp1 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn1 = nn.BatchNorm2d(8)\n",
        "#       self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "#       self.mp2 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn2 = nn.BatchNorm2d(16)\n",
        "#       self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "#       self.bn3 = nn.BatchNorm2d(32)\n",
        "#       self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "#       self.bn4 = nn.BatchNorm2d(64)\n",
        "#       self.conv5 = nn.Conv2d(64,128,3,1,1)\n",
        "#       self.mp3 = nn.MaxPool2d(3, 2)\n",
        "#       self.bn5 = nn.BatchNorm2d(128)\n",
        "#       self.fc1 = nn.Linear(7680, 4096)\n",
        "#       self.fc2 = nn.Linear(4096, 2048)\n",
        "#       self.fc3 = nn.Linear(2048, 1024)\n",
        "#       self.fc4 = nn.Linear(1024,8)\n",
        "#     def forward(self, x):\n",
        "#       x = self.bn1(F.elu(self.mp1(self.conv1(x))))\n",
        "#       x = self.bn2(F.elu(self.mp2(self.conv2(x))))\n",
        "#       x = self.bn3(F.elu(self.conv3(x)))\n",
        "#       x = self.bn4(F.elu(self.conv4(x)))\n",
        "#       x = self.bn5(F.elu(self.mp3(self.conv5(x))))\n",
        "#       x = x.view(int(x.size(0)), -1)\n",
        "#       x = F.elu(F.dropout(self.fc1(x)))\n",
        "#       x = F.elu(F.dropout(self.fc2(x)))\n",
        "#       x = F.elu(F.dropout(self.fc3(x)))\n",
        "#       x = self.fc4(x)\n",
        "#       return x\n",
        "\n",
        "#TRY 3\n",
        "# class KaggleNN(nn.Module):\n",
        "#     def __init__(self, arch):\n",
        "#       super(KaggleNN, self).__init__()\n",
        "#       self.arch = arch\n",
        "#       self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "#       self.mp1 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn1 = nn.BatchNorm2d(8)\n",
        "#       self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "#       self.mp2 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn2 = nn.BatchNorm2d(16)\n",
        "#       self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "#       self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "#       self.conv5 = nn.Conv2d(64,128,3,1,1)\n",
        "#       self.mp4 = nn.MaxPool2d(5, 2)        \n",
        "#       self.fc1 = nn.Linear(5632, 4096)\n",
        "#       self.fc2 = nn.Linear(4096, 2048)\n",
        "#       self.fc3 = nn.Linear(2048, 1024)\n",
        "#       self.fc4 = nn.Linear(1024,8)\n",
        "#     def forward(self, x):\n",
        "#       x = self.bn1(F.leaky_relu(self.mp1(self.conv1(x))))\n",
        "#       x = self.bn2(F.leaky_relu(self.mp2(self.conv2(x))))\n",
        "#       x = self.conv5(self.conv4(self.conv3(x)))\n",
        "#       x = self.mp4(x)\n",
        "#       x = x.view(int(x.size(0)), -1)\n",
        "#       x = F.dropout(F.leaky_relu(self.fc1(x)))\n",
        "#       x = F.dropout(F.leaky_relu(self.fc2(x)))\n",
        "#       x = F.dropout(F.leaky_relu(self.fc3(x)))\n",
        "#       x = self.fc4(x)\n",
        "#       return x\n",
        "\n",
        "#TRY 4-6\n",
        "# class Flatten(nn.Module):\n",
        "#     def forward(self, x):\n",
        "#         return x.view(int(x.size(0)), -1)\n",
        "# class KaggleNN(nn.Module):\n",
        "#   def __init__(self, arch):\n",
        "#     super(KaggleNN, self).__init__()\n",
        "#     self.arch = arch\n",
        "#     self.model = nn.Sequential(\n",
        "#         nn.Conv2d(3, 8, kernel_size=3, padding=1),\n",
        "#         nn.BatchNorm2d(8),\n",
        "#         nn.ReLU(inplace=True),\n",
        "        \n",
        "#         nn.Conv2d(8,16,3,1),\n",
        "#         nn.BatchNorm2d(16),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.MaxPool2d(kernel_size=2, stride=2),\n",
        "        \n",
        "#         nn.Conv2d(16,32,3,1),\n",
        "#         nn.BatchNorm2d(32),\n",
        "#         nn.ReLU(True),\n",
        "        \n",
        "#         nn.Conv2d(32,64,3,1),\n",
        "#         nn.BatchNorm2d(64),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.MaxPool2d(2,2),\n",
        "        \n",
        "#         nn.Conv2d(64,128,3,1),\n",
        "#         nn.BatchNorm2d(128),\n",
        "#         nn.ReLU(True),\n",
        "        \n",
        "#         nn.Conv2d(128,256,3,1),\n",
        "#         nn.BatchNorm2d(256),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.MaxPool2d(2,2),\n",
        "        \n",
        "#         nn.AdaptiveAvgPool2d((7, 7)),\n",
        "#         Flatten(),\n",
        "        \n",
        "#         nn.Linear(12544, 8192),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.Dropout(),\n",
        "        \n",
        "#         nn.Linear(8192, 4096),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.Dropout(),\n",
        "        \n",
        "#         nn.Linear(4096, 4096),\n",
        "#         nn.ReLU(True),\n",
        "#         nn.Dropout(),     \n",
        "        \n",
        "#         nn.Linear(4096, 8),\n",
        "#     )\n",
        "\n",
        "#   def forward(self, x):\n",
        "#     x = self.model(x)\n",
        "#     return x\n",
        "\n",
        "#Try 7+\n",
        "# class KaggleNN(nn.Module):\n",
        "#     def __init__(self, arch):\n",
        "#       super(KaggleNN, self).__init__()\n",
        "#       self.arch = arch\n",
        "#       self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "#       self.mp1 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn1 = nn.BatchNorm2d(8)\n",
        "#       self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "#       self.mp2 = nn.MaxPool2d(5, 2)\n",
        "#       self.bn2 = nn.BatchNorm2d(16)\n",
        "#       self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "#       self.bn3 = nn.BatchNorm2d(32)\n",
        "#       self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "#       self.bn4 = nn.BatchNorm2d(64)\n",
        "#       self.conv5 = nn.Conv2d(64,128,3,1,1)\n",
        "#       self.bn5 = nn.BatchNorm2d(128)\n",
        "#       self.mp3 = nn.MaxPool2d(5, 2)     \n",
        "#       self.bn6 = nn.BatchNorm1d(2048)\n",
        "#       self.bn7 = nn.BatchNorm1d(2048)\n",
        "#       self.fc1 = nn.Linear(5632, 2048)\n",
        "#       self.fc2 = nn.Linear(2048, 2048)\n",
        "#       self.fc3 = nn.Linear(2048,8)\n",
        "#       self.prelu1 = nn.PReLU()\n",
        "#       self.prelu2 = nn.PReLU()\n",
        "#       self.prelu3 = nn.PReLU()\n",
        "#       self.prelu4 = nn.PReLU()\n",
        "#       self.prelu5 = nn.PReLU()\n",
        "#       self.prelu6 = nn.PReLU()\n",
        "#       self.prelu7 = nn.PReLU()\n",
        "#     def forward(self, x):\n",
        "#       x = self.mp1(self.bn1(self.prelu1(self.conv1(x))))\n",
        "#       x = self.mp2(self.bn2(self.prelu2(self.conv2(x))))\n",
        "#       x = self.bn3(self.prelu3(self.conv3(x)))\n",
        "#       x = self.bn4(self.prelu4(self.conv4(x)))\n",
        "#       x = self.bn5(self.prelu5(self.conv5(x)))\n",
        "#       x = self.mp3(x)\n",
        "#       x = x.view(int(x.size(0)), -1)\n",
        "#       x = F.dropout(self.bn6(self.prelu6(self.fc1(x))))\n",
        "#       x = F.dropout(self.bn7(self.prelu7(self.fc2(x))))\n",
        "#       x = self.fc3(x)\n",
        "#       return x"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zQkvz6XxQe8d",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "\n",
        "class KaggleNN(nn.Module):\n",
        "    def __init__(self, arch):\n",
        "      super(KaggleNN, self).__init__()\n",
        "      self.arch = arch\n",
        "      self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "      self.mp1 = nn.MaxPool2d(5, 2)\n",
        "      self.bn1 = nn.BatchNorm2d(8)\n",
        "      self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "      self.mp2 = nn.MaxPool2d(5, 2)\n",
        "      self.bn2 = nn.BatchNorm2d(16)\n",
        "      self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "      self.bn3 = nn.BatchNorm2d(32)\n",
        "      self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "      self.bn4 = nn.BatchNorm2d(64)\n",
        "      self.conv5 = nn.Conv2d(64,128,3,1,1)\n",
        "      self.bn5 = nn.BatchNorm2d(128)\n",
        "      self.mp3 = nn.MaxPool2d(5, 2)     \n",
        "      self.bn6 = nn.BatchNorm1d(2048)\n",
        "      self.bn7 = nn.BatchNorm1d(2048)\n",
        "      self.fc1 = nn.Linear(5632, 2048)\n",
        "      self.fc2 = nn.Linear(2048, 2048)\n",
        "      self.fc3 = nn.Linear(2048,8)\n",
        "      self.prelu1 = nn.PReLU()\n",
        "      self.prelu2 = nn.PReLU()\n",
        "      self.prelu3 = nn.PReLU()\n",
        "      self.prelu4 = nn.PReLU()\n",
        "      self.prelu5 = nn.PReLU()\n",
        "      self.prelu6 = nn.PReLU()\n",
        "      self.prelu7 = nn.PReLU()\n",
        "    def forward(self, x):\n",
        "      x = self.mp1(self.bn1(self.prelu1(self.conv1(x))))\n",
        "      x = self.mp2(self.bn2(self.prelu2(self.conv2(x))))\n",
        "      x = self.bn3(self.prelu3(self.conv3(x)))\n",
        "      x = self.bn4(self.prelu4(self.conv4(x)))\n",
        "      x = self.bn5(self.prelu5(self.conv5(x)))\n",
        "      x = self.mp3(x)\n",
        "      x = x.view(int(x.size(0)), -1)\n",
        "      x = F.dropout(self.bn6(self.prelu6(self.fc1(x))))\n",
        "      x = F.dropout(self.bn7(self.prelu7(self.fc2(x))))\n",
        "      x = self.fc3(x)\n",
        "      return x"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-EVC6r7_HYA8",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def weights_init(m):\n",
        "  if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):\n",
        "      torch.nn.init.xavier_uniform_(m.weight)\n",
        "      if m.bias is not None:\n",
        "          torch.nn.init.zeros_(m.bias)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Td1-ldp4QiDX",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import datetime\n",
        "\n",
        "def preds_to_csv(names,y):\n",
        "    df = pd.DataFrame({'Id': names, 'Category': y})\n",
        "    df.set_index('Id',inplace=True)\n",
        "    df.to_csv(str(str(datetime.datetime.now().time())+'_submission.csv'))\n",
        "    print(\"saved predictions\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Q387zcMWJ5iO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!ls"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o7jwRgtkiIEh",
        "colab_type": "text"
      },
      "source": [
        "# 4g"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "17mCfiHJPrWg",
        "colab": {}
      },
      "source": [
        "import adabound \n",
        "\n",
        "is_train = True\n",
        "is_key_frame = False\n",
        "arch = \"pytorch_kaggle1.5\"\n",
        "params = {'batch_size': 64,'shuffle': True,'num_workers': 4}\n",
        "hyperparams = {\"num_epochs\":3,\"criterion\":nn.CrossEntropyLoss()}\n",
        "model = KaggleNN(arch).to(device)\n",
        "model.apply(weights_init)\n",
        "hyperparams[\"optimizer\"] = adabound.AdaBound(model.parameters(), lr=1e-3, final_lr=0.1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "72TAN9ZBk4e4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "mod_data = modelling(model,is_train,is_key_frame,arch,params,hyperparams)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BorxxSySk1Tl",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data.append(mod_data)\n",
        "data_track(models_data,save=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5yF-EILlo7oT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "model = KaggleNN(arch).to(device)\n",
        "model.load_state_dict(torch.load(os.getcwd()+\"/\"+arch))\n",
        "model.eval()\n",
        "val_params = {'batch_size': 64,'shuffle': False,'num_workers': 4}\n",
        "_,val_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                         is_key_frame=False,\n",
        "                                         params=val_params)\n",
        "rand_acc,rand_predicted_list,rand_groundtruth_list = get_accuracy(model, val_loader)\n",
        "rand_pairs = move_val_acc(rand_predicted_list, rand_groundtruth_list)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9i4qiguGkhlk",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "accs = [[p[0] for p in rand_pairs]+[rand_acc]]\n",
        "cols = ['reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup',\"overall\"]\n",
        "df = pd.DataFrame(accs,columns=cols)\n",
        "print(\"accuracies\")\n",
        "df"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PlaDX3Ye3WrG",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cm = confusion_matrix(rand_groundtruth_list, \n",
        "                 rand_predicted_list)\n",
        "cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
        "fig, ax = plt.subplots()\n",
        "classes = ['reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup']\n",
        "im = ax.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)\n",
        "ax.figure.colorbar(im, ax=ax)\n",
        "ax.set(xticks=np.arange(cm.shape[1]),\n",
        "       yticks=np.arange(cm.shape[0]),\n",
        "       xticklabels=classes, yticklabels=classes,\n",
        "       title=\"confusion matrix for Kaggle model\",\n",
        "       ylabel='True label',\n",
        "       xlabel='Predicted label');\n",
        "plt.xticks(rotation=90);"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LuWxN6b_7OKT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "_,_,test_loader = load_preprocess_data(is_train=False,\n",
        "                                          is_key_frame=False,\n",
        "                                          params=val_params)\n",
        "names, kaggle_preds = test_predict(model,test_loader)\n",
        "preds_to_csv(names, kaggle_preds)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gL2lhWErD32c",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}